package modelo;

import geometria.*;



/**
 * 
 * Clase madre de todas las aeronaves
 *
 */
public abstract class AeroNave {
	
	protected Coordenada posicion;
	protected Velocidad  velocidad;
	protected Rectangulo limites;
	//protected Rectangle2D.Double limites;
	//protected Ellipse2D.Double limites;
	protected Trayectoria trayectoria; 
	protected Double carreteo,peso, alto, ancho;
	protected Boolean aterrizado=false;
	
	public AeroNave(Coordenada pos) {
		this.posicion = pos;
		trayectoria = new Trayectoria();
	}

	/**
	 * 	  
	 * @param milisegundos tiempo transcurrido en base al cual tengo que mover, en milisegundos.
	 * Esto debe estar definido para cada tipo de aeronave
	 * @throws TrayectoriaVaciaException 
	 */
	/* public abstract void actualizarPosicion(Double milisegundos) throws TrayectoriaVaciaException;
	 /**
	  * @return La velocidad actual
	  */
	public Velocidad getVelocidad() {
		return velocidad;
	}
	
	public boolean esAterrizableEn(Pista unaPista) {
		return unaPista.soportaCarreteo(this.carreteo) && unaPista.soportaPeso(this.peso);
	}
	
	public boolean chocoContra(AeroNave otra)
	{
		
		Rectangulo limitesOtra =  otra.getLimites();
		return limitesOtra.intersecta(this.limites);
		/*RectangularShape limitesOtra =  otra.getLimites();
		RectangularShape l = this.limites;
		//return limitesOtra.intersects((Rectangle2D)this.limites);
		//TODO esto no funciona
		return false;*/
	}

	public Coordenada getPosicion() {
		Coordenada c = new Coordenada(posicion.getX(),posicion.getY());
		return c;
	}
	
	
	private Rectangulo getLimites() {
		return this.limites;
	}

	public void agregarPuntoATrayectoria (Coordenada nuevoPunto) {
		trayectoria.agregarPunto(nuevoPunto);
	}
	
	public void aterrizar(Pista p){
		this.aterrizado = true;
	}
	protected abstract Double getModuloVelocidadDefault();
		
	
	private void actualizarLimites(){
		this.limites = new Rectangulo(posicion.getX() - (this.ancho/2), 
				posicion.getY() - (this.alto/2), this.ancho, this.alto);
	}
	public void actualizarPosicion(Double tiempo) {

		if (tiempo < 0)
			throw new TiempoInvalidoException();

		// Si no tenemos puntos en la trayectoria nos movemos en la direccion
		// que tenemos,
		if (this.trayectoria.esVacia()) {
			this.posicion = this.posicion.moverConVelocidad(this.velocidad, tiempo);
			this.posicion = Escenario.getInstance().ajustarCoordenada(posicion);
			this.actualizarLimites();
			return;
		}
		
		try {
			
			if (this.posicion.coincideCon(this.trayectoria.obtenerProximoPunto(), 1D))
			{
					trayectoria.avanzarPunto();
					//this.velocidad = new Velocidad(this.trayectoria.obtenerProximoPunto(), this.getModuloVelocidadDefault());
			}
			
			this.velocidad = new Velocidad(this.posicion,
					this.trayectoria.obtenerProximoPunto(),
					this.getModuloVelocidadDefault());
			this.posicion.mover(trayectoria.obtenerProximoPunto(), tiempo,
					this.velocidad.getModulo());
			this.posicion = Escenario.getInstance().ajustarCoordenada(posicion);
			//this.limites.marcoNuevo(posicion.getX() - (this.ancho/2), 
			//		posicion.getY() - (this.alto/2), this.ancho, this.alto);
			this.actualizarLimites();
			//this.velocidad = new Velocidad(this.trayectoria.obtenerProximoPunto(), this.getModuloVelocidadDefault());
			
			
		}
		
		catch (TrayectoriaVaciaException e) {
			this.posicion = this.posicion.moverConVelocidad(this.velocidad, tiempo);
			this.posicion = Escenario.getInstance().ajustarCoordenada(posicion);
			//this.limites.marcoNuevo(posicion.getX() - (this.ancho/2), 
			//		posicion.getY() - (this.alto/2), this.ancho, this.alto);
			this.actualizarLimites();
		}
	}

	public boolean estaAterrizado() {
		
		return this.aterrizado;
	}
	
	

	
}
